<template>
    <div>
        <div class="e-table" style="background-color: #fff; padding-bottom: 0">
            <!-- 头部buttons -->
            <div class="top" style="margin-bottom: 10px">
                <div class="left" style="width: 100%">
                    <div>
                        <!-- @click="openNewPage('tenderList')" -->
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="importList"
                            v-if="canAddDel"
                            >引入清单</el-button
                        >
                        <!-- :key="refDetailsKey" -->
                        <el-select
                            v-model="detailsDataCurDtlId"
                            placeholder="请选择包件"
                            style="width: 300px; margin-left: 10px"
                            @change="handleNodeClick"
                        >
                            <el-option
                                v-for="item in detailsData"
                                :key="item.dtlId"
                                :label="item.itemNo + ' ' + item.name"
                                :value="item.dtlId"
                            >
                            </el-option>
                        </el-select>
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="importList2"
                            v-if="Secret"
                            >100章-101-a</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="importList3"
                            v-if="Secret"
                            >100章-101-b</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="importList4"
                            v-if="Secret"
                            >101-1-a</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="importList5"
                            v-if="Secret"
                            >测试bug</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="printMap1"
                            v-if="Secret"
                            >打印tableData</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="printMap"
                            v-if="Secret"
                            >打印mapTableData</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="printMap2"
                            v-if="Secret"
                            >打印cloneMapInitTableData</el-button
                        >
                        <el-button
                            size="small"
                            class="btn-greenYellow"
                            @click="printMap3"
                            v-if="Secret"
                            >打印wholeListData</el-button
                        >
                        <el-button size="small" class="btn-greenYellow" @click="save" v-if="Secret"
                            >保存</el-button
                        >
                    </div>
                </div>
            </div>
        </div>
        <div class="ruleMessage" v-if="ruleMessage">
            {{ ruleMessage }}
        </div>
        <div class="e-tree-table2" style="width: 98%; padding: auto">
            <el-table
                ref="tableRef"
                border
                row-key="listId"
                :data="tableData"
                :tree-props="{
                    children: 'children',
                    hasChildren: 'hasChildren'
                }"
                :load="onload"
                lazy
                :row-class-name="tableRowClassName"
                :key="dtlIndex"
                @row-click="rowClick"
                v-if="tableRefState"
                style="width: 100%"
                :max-height="$store.state.tableHeight"
                v-sortTable="{ tableData: tableData, _this: this, ref: 'tableRef' }"
            >
                <el-table-column label="操作" width="200">
                    <template slot-scope="{ row }">
                        <div class="oparation_box">
                            <!-- <img
                                src="@/assets/btn/sub.png"
                                class="add_sub"
                                @click="addChilden(row, levelIsTotal(row))"
                                title="添加子级"
                                v-if="
                                    (row.isListLeaf || row.label === '项') &&
                                    canAddDel
                                "
                            /> -->
                            <i
                                class="el-icon-delete"
                                style="font-size: 24px; color: #e9513e"
                                @click="onDelNode(row)"
                                v-if="canAddDel"
                                title="删除"
                            ></i>
                        </div>
                    </template>
                </el-table-column>
                <el-table-column prop="code" label="细目编号" min-width="150">
                    <template slot-scope="{ row }">
                        <el-input
                            v-model="row.code"
                            placeholder="请输入内容"
                            v-if="row.label === '项' && canAddDel"
                        ></el-input>
                        <span v-else>{{ row.code }}</span>
                    </template>
                </el-table-column>
                <el-table-column
                    prop="codeName"
                    label="细目名称"
                    min-width="150"
                    :show-overflow-tooltip="true"
                >
                    <template slot-scope="{ row }">
                        <el-input
                            v-model="row.codeName"
                            placeholder="请输入内容"
                            v-if="row.label === '项' && canAddDel"
                        ></el-input>
                        <span v-else>{{ row.codeName }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="label" label="标识" width="150">
                    <!-- <template slot-scope="{ row }">
                                <el-input
                                    v-model="row.subitemName"
                                    placeholder="请输入内容"
                                    v-if="row.inputState"
                                ></el-input>
                                <span v-else>{{ row.subitemName }}</span>
                            </template> -->
                </el-table-column>
                <el-table-column
                    prop="structureNamePaths"
                    label="结构部位名称"
                    width="150"
                    :show-overflow-tooltip="true"
                >
                    <template slot-scope="{ row }">
                        <span>{{ row.structureNamePaths }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="unit" label="计量单位" width="130">
                    <template slot-scope="{ row }">
                        <el-select
                            v-model="row.unit"
                            placeholder="请选择"
                            v-if="row.label === '项'"
                        >
                            <el-option
                                v-for="item in unitMeasure"
                                :key="item.value"
                                :label="item.label"
                                :value="item.value"
                            >
                            </el-option>
                        </el-select>
                        <span v-else>{{ row.unit }}</span>
                    </template>
                </el-table-column>
                <el-table-column prop="priceType" label="单价类型" width="130">
                    <template slot-scope="{ row }">
                        <el-select
                            v-model="row.priceType"
                            placeholder="请选择"
                            v-if="row.isListLeaf"
                            :disabled="!canAddDel"
                            @change="priceTypeChange(row, 'priceType')"
                        >
                            <el-option label="全单价" :value="1"></el-option>
                            <el-option label="劳务单价" :value="2"></el-option>
                        </el-select>
                        <!-- <div v-else>{{ ['全单价','劳务单价'][row.unitPriceType-1] }}</div> -->
                    </template>
                </el-table-column>
                <el-table-column prop="num" label="数量" width="130">
                    <!-- 最子级或者结构层显示数量 -->
                    <template
                        slot-scope="{ row }"
                        v-if="row.isListLeaf || row.isLeaf || row.isAllLeaf || row.structurePaths"
                    >
                        <el-input
                            v-model="row.num"
                            placeholder="请输入内容"
                            v-if="row.structureNamePaths && !levelIsTotal(row) && canEdit"
                            v-enterFloat2Neg="{
                                set: row,
                                key: 'num'
                            }"
                            @input="numBlur(row, 'num')"
                        ></el-input>
                        <span v-else>{{ isNaN(row.num) ? 0 : row.num }}</span>
                        <i
                            slot="suffix"
                            class="el-icon-tickets"
                            @click="showHistory(row, 'numUpdateHistory')"
                            v-if="row.numUpdateHistory && row.numUpdateHistory.length !== 0"
                        ></i>
                    </template>
                </el-table-column>
                <!-- 111111 -->
                <el-table-column label="招标限价">
                    <!--   b、有“项”标识细目：在“项”标识最子级细目层填写劳务单价，同时还要计算“项”标识细目的第一个“清单”标识最子级细目的劳务单价，计算公式=子级的金额之和/预算数量
 -->
                    <el-table-column prop="price" label="劳务单价" width="130">
                        <!-- :disabled="!row.children && !levelIsTotal(row)" -->
                        <!-- 这里用blur，因为计算比较多 -->
                        <template slot-scope="{ row }">
                            <el-input
                                v-model="row.price"
                                placeholder="请输入内容"
                                v-if="row.isLeaf && canEdit && !levelIsTotal(row)"
                                v-enterFloatNeg="{
                                    set: row,
                                    key: 'price'
                                }"
                                :disabled="!row.children && !levelIsTotal(row)"
                                @input="priceBlur(row, 'price')"
                            ></el-input>
                            <span v-else>{{ row.price }}</span>
                            <i
                                slot="suffix"
                                class="el-icon-tickets"
                                @click="showHistory(row, 'priceUpdateHistory')"
                                v-if="row.priceUpdateHistory && row.priceUpdateHistory.length !== 0"
                            ></i>
                        </template>
                    </el-table-column>
                    <el-table-column prop="materialPrice" label="甲供材料单价" width="130">
                        <template slot-scope="{ row }" v-if="row.isListLeaf">
                            {{ row.materialPrice === 0 ? '' : row.materialPrice }}
                        </template>
                    </el-table-column>
                    <!-- <el-table-column prop="lossRate" label="损耗率" width="130">
                        v-if="row.priceType === 2" 如果单价类型是劳务单价，则“甲供设备单价”、“甲供其他单价”可编辑
                        <template slot-scope="{ row }" v-if="row.priceType === 2">
                            v-if="row.isListLeaf && canEdit" 在标识为“清单”的最子级细目层填写
                            <el-input
                                v-model="row.lossRate"
                                placeholder="请输入内容"
                                v-if="row.isListLeaf && canEdit"
                                v-enterInteger2="{
                                    set: row,
                                    key: 'lossRate'
                                }"
                                @input="blurLossRate(row, 'lossRate')"
                            ></el-input>
                            <span v-else>{{ row.lossRate }}</span>
                        </template>
                    </el-table-column> -->
                    <!-- <el-table-column
                        prop="materialPriceLoss"
                        label="甲供材料（含损耗）单价"
                        width="180"
                    >
                        <template slot-scope="{ row }">
                            {{ row.materialPriceLoss === 0 ? '' : row.materialPriceLoss }}
                        </template>
                    </el-table-column> -->
                    <el-table-column prop="equipmentPrice" label="甲供设备单价" width="130">
                        <!-- v-if="row.priceType === 2" 如果单价类型是劳务单价，则“甲供设备单价”、“甲供其他单价”可编辑 -->
                        <template slot-scope="{ row }" v-if="row.priceType === 2">
                            <!-- v-if="row.isListLeaf && canEdit" 在标识为“清单”的最子级细目层填写 -->
                            <el-input
                                v-model="row.equipmentPrice"
                                placeholder="请输入内容"
                                v-if="row.isListLeaf && canEdit"
                                v-enterFloat="{
                                    set: row,
                                    key: 'equipmentPrice'
                                }"
                                @input="subtotal(row, 'equipmentPrice')"
                            ></el-input>
                            <span v-else>{{ row.equipmentPrice }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column prop="otherPrice" label="甲供其他单价" width="130">
                        <!-- v-if="row.priceType === 2" 如果单价类型是劳务单价，则“甲供设备单价”、“甲供其他单价”可编辑 -->
                        <template slot-scope="{ row }" v-if="row.priceType === 2">
                            <!-- v-if="row.isAllLeaf && canEdit" 在标识为“清单”的最子级细目层填写 -->
                            <el-input
                                v-model="row.otherPrice"
                                placeholder="请输入内容"
                                v-if="row.isListLeaf && canEdit"
                                v-enterFloat="{
                                    set: row,
                                    key: 'otherPrice'
                                }"
                                @input="subtotal(row, 'otherPrice')"
                            ></el-input>
                            <span v-else>{{ row.otherPrice }}</span>
                        </template>
                    </el-table-column>
                    <el-table-column prop="subtotal" label="小计" width="130">
                        <template slot-scope="{ row }">
                            {{ row.subtotal === 0 ? '' : row.subtotal }}
                        </template>
                    </el-table-column>
                </el-table-column>
                <el-table-column prop="amount" label="劳务金额" width="100">
                    <template slot-scope="{ row }">
                        <el-input
                            v-model="row.amount"
                            placeholder="请输入内容"
                            v-if="row.unit === '总额' && canEdit"
                            v-enterAllInteger1
                            @input="amountBlur(row, 'amount')"
                        ></el-input>
                        <span v-else>{{ row.amount }}</span>
                        <i
                            slot="suffix"
                            class="el-icon-tickets"
                            @click="showHistory(row, 'amountUpdateHistory')"
                            v-if="row.amountUpdateHistory && row.amountUpdateHistory.length !== 0"
                        ></i>
                    </template>
                </el-table-column>
                <el-table-column prop="rule" label="计量规则、计价规则" width="200">
                    <template slot-scope="{ row }">
                        <el-input
                            v-model="row.rule"
                            placeholder="请输入内容"
                            v-if="canEdit"
                        ></el-input>
                        <span v-else>{{ row.rule }}</span>
                    </template>
                </el-table-column>
            </el-table>
        </div>
        <!-- dialog -->
        <el-dialog :visible.sync="historyDialogVisible" width="70%">
            <el-table
                :data="historyTableData"
                style="width: 100%; margin-bottom: 20px"
                row-key="id"
                border
                default-expand-all
                :max-height="$store.state.tableHeight"
                ref="table"
                v-sortTable="{ tableData: tableData, _this: this, ref: 'table' }"
            >
                <el-table-column prop="modifier" label="修改人" width="200"> </el-table-column>
                <el-table-column prop="createTime" label="修改时间" width="100"> </el-table-column>
                <el-table-column prop="originalContent" label="原数据" width="100">
                </el-table-column>
                <el-table-column prop="modifiedContent" label="修改后数据" width="100">
                </el-table-column>
            </el-table>
            <span slot="footer" class="dialog-footer">
                <el-button @click="historyDialogVisible = false">取 消</el-button>
            </span>
        </el-dialog>
    </div>
</template>
<script>
import applyRequest from '@/api/tender/apply.js'
import tenderRequest from '@/api/tender/tender.js'
import {
    // eslint-disable-next-line no-unused-vars
    toLocation,
    vueDom,
    selectDataClient,
    // eslint-disable-next-line no-unused-vars
    openAppClient,
    getItemOfTreeArr,
    getUuid
} from '@/utils/common.js'
import { uidBuilder } from '@/api/base/uid.js'
// eslint-disable-next-line no-unused-vars
import { mapMutations, mapState, mapActions } from 'vuex'
// import leaseSetAddVue from '../../../settlementManagement/equipmentBilling/leaseSet/leaseSetAdd.vue'

export default {
    props: {
        // 包件数据
        detailsData: {
            type: Array,
            default: function () {
                return []
            }
        },
        // 清单数据
        tableData: {
            type: Array,
            default: function () {
                return []
            }
        },
        // 审核状态
        auditState: {
            type: Object,
            default: function () {
                return {}
            }
        }
    },
    model: {
        prop: 'tableData',
        event: 'change'
    },
    computed: {
        ...mapState({
            unitMeasure: state => state.biddingApplication.dictionaries.unitMeasure //计量单位
        }),
        tenderId () {
            return this.$route.query.billid
        },
        // 当前选择包件的index
        dtlIndex () {
            return this.detailsData.findIndex(item => this.dtlId === item.dtlId)
        },
        // 审核中不能增删
        canAddDel () {
            if (this.auditState?.canModify === false || Object.keys(this.auditState).length === 0) {
                return false
            } else {
                return true
            }
        },
        // 审核完成后不能修改
        canEdit () {
            if (Object.keys(this.auditState).length === 2) {
                return false
            } else {
                return true
            }
        }
    },
    watch: {
        // 包件数据
        detailsData: {
            handler (newVal) {
                // 处理数据获得包件列表
                if (newVal.length === 0) {
                    this.$emit('change', [])
                    // this.tableData = []
                    this.dtlId = ''
                    this.detailsDataCurDtlId = ''
                    // this.refDetailsKey += 1
                } else {
                    // 如果没选择过包件，包件id就默认第一个
                    if (this.dtlId === '' && this.selectDetailState === false) {
                        this.dtlId = newVal[0].dtlId
                    } else {
                        // 寻找当前包件数据里是否有当前id（主要判断被删情况）
                        const findVal = newVal.find(item => item.dtlId === this.dtlId)
                        if (findVal) {
                            this.dtlId = findVal.dtlId
                        } else {
                            this.dtlId = ''
                        }
                    }
                }
                // if (newVal.length === 1) {
                //     setTimeout(() => {
                //         $('.el-tree-node:first')?.addClass('is-current')
                //     }, 100)
                // }
            },
            deep: true
        },
        // 当前选择的包件id
        dtlId (newVal) {
            this.detailsDataCurDtlId = newVal
            if (
                newVal !== '' &&
                JSON.stringify(this.tableData[this.dtlIndex]) ===
                    JSON.stringify(this.cloneTableData[this.dtlIndex])
            ) {
                this.getData() // 获取清单数据
                this.getAllData() // 获取清单全部数据（已选功能）
            }
            if (newVal === '') {
                this.tableData = []
            }
        },
        tableData: {
            handler (newVal) {
                console.log('执行watch tableData')
                // 计算招标限价
                this.allTableData[this.dtlIndex] = newVal
                // const temp =  JSON.parse(JSON.stringify(newVal))
                // const tempFun = temp=>{
                //     temp.forEach(item=>{
                //         while(item.children) {
                //             console.log('watch item', item)
                //             tempFun(item.children)
                //         }
                //     })
                // }
                // tempFun(temp)
            },
            deep: true
        },
        mapTableData: {
            handler (newVal) {
                console.log('执行watch mapTableData')
                // console.log('watch mapTableData', newVal)
                this.allMapTableData[this.dtlIndex] = newVal
            },
            deep: true
        },
        // deleteTableData: {
        //     handler (newVal) {
        //         // console.log('watch mapTableData', newVal)
        //         this.allDeleteTableData[this.dtlIndex] = newVal
        //     },
        //     deep: true
        // },
        wholeListData: {
            handler (newVal) {
                // console.log('watch mapTableData', newVal)
                this.allWholeListData[this.dtlIndex] = newVal
            },
            deep: true
        }
    },
    data () {
        return {
            detailsOfProposedArr: [],
            // tableData: [],
            cloneTableData: [],
            mapTableData: {},
            // deleteTableData: [],
            addList: [], // 缓存新增数据
            structure: [], // 结构部位
            temp: [],
            count: 0,
            dtlId: '',
            allTableData: [],
            allMapTableData: [],
            // allDeleteTableData: [],
            Secret: false,
            ruleMessage: '',
            cloneMapInitTableData: {},
            startEndStake: '', // 起止桩号
            // ruleRes: [] // 用来最后一步验证
            wholeListData: {}, // 当前包件对应清单的所有数据（已选功能）
            allWholeListData: [],
            tableRefState: true,
            detailsDataCurDtlId: '',
            // refDetailsKey: 0,
            selectDetailState: false,
            historyTableData: [],
            historyDialogVisible: false
        }
    },
    created () {
        // this.getData()
        // this.findByApplyId()
        // this.importList()
        this.setUnitMeasur() // 计量单位字典
    },
    mounted () {
        vueDom(
            // 默认0为选中项
            () => {
                $('.el-tree-node:first')?.addClass('is-current')
            },
            () => {
                return $('.el-tree-node:first')?.attr('class')?.includes('is-current')
            }
        )
        const temp = []
        document.onkeydown = e => {
            temp.push(e.keyCode)
            if (temp.length > 4) {
                temp.splice(0, 1)
            }
            if (temp.join('') === '38384040') {
                this.Secret = true
                document.onkeydown = undefined
            }
        }
    },
    methods: {
        ...mapMutations(['setAuditParams', 'setSelectedInfo']),
        ...mapActions('biddingApplication', ['setUnitMeasur']),
        // 没什么意义，最终还是要判断每行变化没有
        // ifChange (row, attr) {
        //     if (row[attr] !== this.cloneMapInitTableData[row.listId][attr]) {
        //         row.changeState = 2
        //         // wholeListData也要做改变，已选数据需要
        //         this.wholeListData[row.listId].changeState = 2
        //     } else {
        //         row.changeState = 0
        //     }
        // },
        printMap1 () {
            console.log(this.tableData)
        },
        printMap () {
            console.log(this.mapTableData)
        },
        printMap2 () {
            console.log(this.cloneMapInitTableData)
        },
        printMap3 () {
            console.log(this.wholeListData)
        },
        showHistory (row, arg) {
            this.historyDialogVisible = true
            this.historyTableData = row[arg]
        },
        getAllData (packageId = this.dtlId) {
            tenderRequest.allListByPackageId({ packageId }).then(res => {
                this.wholeListData = {}
                res.forEach(item => {
                    // wholeListData也需要children
                    item.children = []
                    res.forEach(item2 => {
                        if (item.listId === item2.parentId) {
                            item.children.push(item2)
                        }
                    })
                    // 最子级
                    if (item.isLeaf === 1) {
                        res.forEach(item2 => {
                            if (item2.parentId === item.listId) {
                                item.applyStructureList = []
                                // 增加结构（客户端返显）
                                item.applyStructureList.push(JSON.parse(JSON.stringify(item2)))
                            }
                        })
                    }
                    this.wholeListData[item.listId] = item
                    this.wholeListData[item.listId].changeState = 0
                    this.saveCloneMap(item)
                    // 懒加载也需要全部数据，这样导入数据才能保留之前数据
                    this.mapTableData[item.listId] = item
                    this.mapTableData[item.listId].changeState = 0
                })
                this.wholeListData[0] = {
                    children: Object.values(this.wholeListData)
                }
            })
        },
        rowClick (row) {
            console.log('row', row)
        },
        // 损耗率焦点离开事件
        blurLossRate (row) {
            // 甲供材料单价（损耗）=甲供材料单价*（1+损耗率/100）
            row.materialPriceLoss = parseFloat(
                (row.materialPrice * (1 + row.lossRate / 100)).toFixed(2)
            )
            this.subtotal(row) // 小计
        },
        // 小计，自动计算，等于劳务单价+甲供材料单价（损耗）+甲供设备单价+甲供其他单价
        subtotal (row) {
            // console.log('parseFloat(row.price)', parseFloat(row.price))
            // console.log('parseFloat(row.materialPriceLoss)', parseFloat(row.materialPriceLoss))
            // console.log('parseFloat(row.equipmentPrice)', parseFloat(row.equipmentPrice))
            // console.log('parseFloat(row.otherPrice)', parseFloat(row.otherPrice))
            // row.subtotal = parseFloat(
            //     (
            //         (parseFloat(row.price) || 0) +
            //         (parseFloat(row.materialPriceLoss) || 0) +
            //         (parseFloat(row.equipmentPrice) || 0) +
            //         (parseFloat(row.otherPrice) || 0)
            //     ).toFixed(2)
            // )
            // 11.2修改需求
            // 小计则用甲供材料单价计算
            row.subtotal = parseFloat(row.materialPrice)
        },
        async handleNodeClick (dtlId) {
            // $('.el-tree-node:first')?.removeClass('is-current')
            const item = this.detailsData.find(item2 => item2.dtlId === dtlId)
            this.selectDetailState = true
            this.dtlId = item.dtlId
            if (this.allTableData[this.dtlIndex] !== undefined) {
                await this.$emit('change', this.allTableData[this.dtlIndex])
                // this.tableData = this.allTableData[this.dtlIndex]
            } else {
                await this.$emit('change', [])
                // this.tableData = []
            }
            if (this.allMapTableData[this.dtlIndex] !== undefined) {
                this.mapTableData = this.allMapTableData[this.dtlIndex]
            } else {
                this.mapTableData = {}
            }
            // if (this.allDeleteTableData[this.dtlIndex] !== undefined) {
            //     this.deleteTableData = this.allDeleteTableData[this.dtlIndex]
            // } else {
            //     this.deleteTableData = []
            // }
            if (this.allWholeListData[this.dtlIndex] !== undefined) {
                this.wholeListData = this.allWholeListData[this.dtlIndex]
            } else {
                this.wholeListData = {}
            }
            // console.log('allTableData', this.allTableData)
            // console.log('allMapTableData', this.allMapTableData)
        },
        async getData (parenId = '0') {
            const res = await tenderRequest.listByPackageId({
                keyword: '',
                packageId: this.dtlId,
                parenId
            })
            res.forEach(item => {
                item.uuid = getUuid()
                item.changeState = 0
                // 处理懒加载
                if (item.isAllLeaf === 0) {
                    item.hasChildren = true
                }
                if (item.price === 0) {
                    item.price = ''
                }
                // 结构层不返billId
                if (item.billId === null) {
                    item.billId = item.subitemId
                    item.deleteState = 0
                }
                this.mapTableData[item.listId] = item
                if (item.parentId === '0') {
                    setTimeout(() => {
                        this.mapTableData[item.listId] = item
                    }, 3000)
                }
            })
            if (parenId === '0') {
                await this.$emit('change', res)
                this.$set(this.mapTableData, '0', {
                    children: this.tableData
                })
            }
            this.cloneTableData[this.dtlIndex] = JSON.parse(JSON.stringify(res))
            return res
        },
        // 根据ID获取该节点的对象
        getIdNode (list, id) {
            for (let i in list) {
                if (list[i].listId == id) {
                    return [list[i]]
                }
                if (list[i].children) {
                    let node = this.getIdNode(list[i].children, id)
                    if (node !== undefined) {
                        return node
                    }
                }
            }
        },
        // 初始化计算
        initCalNum (str) {
            const arrMapValues = Object.values(this.mapTableData)
            const arr = []
            const lastIds = arrMapValues
                .filter(item =>
                    str === 'num' ? item.structurePaths || item.isListLeaf : item.structurePaths
                )
                .filter(item => {
                    if (!arr.includes(item.parentId)) {
                        arr.push(item.parentId)
                        return item
                    }
                })
            lastIds.forEach(item => {
                this.recurCount({
                    parentId: item.parentId,
                    rootId: '0',
                    listField: 'listId',
                    parentField: 'parentId',
                    item,
                    str,
                    type: str === 'num' ? 'float' : 'int'
                })
            })
        },
        // 顶级是否是总额
        levelIsTotal (row) {
            const levels = getItemOfTreeArr(this.tableData, 'listId', row.listId)
            if (levels.find(item => item.unit === '总额') === undefined) {
                return false
            } else {
                return true
            }
        },
        // 记录进cloneMap
        saveCloneMap (row) {
            // console.log('cloneMapInitTableData', this.cloneMapInitTableData)
            // console.log('row.listId', row.listId)
            // console.log('this.cloneMapInitTableDat[row.listId]', this.cloneMapInitTableDat[row.listId])
            if (!this.cloneMapInitTableData[row.listId]) {
                this.cloneMapInitTableData[row.listId] = JSON.parse(JSON.stringify(row))
            }
        },
        // 单价类型
        priceTypeChange (row) {
            // 等于全单价时，清空招标限价，重新计算小计
            if (row.priceType === 1) {
                row._materialPrice = row.materialPrice // 备份一个还原用
                row.materialPrice = 0
                row.lossRate = 0
                row.materialPriceLoss = 0
                row.equipmentPrice = 0
                row.otherPrice = 0
                this.subtotal(row)
            } else {
                if (row._materialPrice) {
                    // 甲供材料单价
                    row.materialPrice = row._materialPrice
                    // 甲供材料（含损耗）单价
                    row.materialPriceLoss = parseFloat(
                        (row.materialPrice * (1 + row.lossRate / 100)).toFixed(2)
                    )
                    // 小计
                    // row.subtotal =
                    //     (parseFloat(row.price) || 0) +
                    //     (parseFloat(row.materialPriceLoss) || 0) +
                    //     (parseFloat(row.equipmentPrice) || 0) +
                    //     (parseFloat(row.otherPrice) || 0)
                    //    // 11.2修改需求
                    // 小计则用甲供材料单价计算
                    row.subtotal = parseFloat(row.materialPrice)
                }
            }
        },
        // 金额修改
        amountBlur (row) {
            row.amount = parseFloat(row.amount)
            // 向上汇总金额
            this.recurCount({
                parentId: row.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                row,
                str: 'amount'
            })
            // 总额向下修改
            if (row.unit === '总额') {
                while (row.children) {
                    row.children.forEach(item => {
                        item.amount = row.amount
                    })
                    row = row.children
                }
            }
        },
        // 数量修改
        numBlur (row) {
            // if (row.num === '') {
            //     row.num = 0
            // }
            // row.price = isNaN(parseFloat(row.price)) ? 0 : parseFloat(row.price)
            // row.num = isNaN(parseFloat(row.num)) ? 0 : parseFloat(row.num)
            // 计算本行金额
            row.amount = Math.round(row.price * row.num)
            // 修改父级applyStructureList里的值
            // this.mapTableData[row.parentId].applyStructureList =
            //     this.mapTableData[row.parentId].children
            // 向上汇总数量
            this.recurCount({
                parentId: row.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                row,
                str: 'num',
                type: 'float'
            })
            // 向上汇总金额
            this.recurCount({
                parentId: row.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                row,
                str: 'amount'
            })
        },
        // 单价修改
        priceBlur (row) {
            // if (row.price === '') {
            //     row.price = 0
            // }
            // 小计
            this.subtotal(row)
            // if (!row.children && !this.levelIsTotal(row)) return
            // row.price = isNaN(parseFloat(row.price)) ? 0 : parseFloat(row.price)
            // console.log('row.price', row.price)
            row.num = isNaN(parseFloat(row.num)) ? 0 : parseFloat(row.num)
            // 向下修改
            if (row.children) {
                row.children.forEach(item => {
                    item.price = row.price
                    this.$set(this.mapTableData, item.listId, item)
                    // this.mapTableData[item.listId] = item
                })
            }
            // 向上修改
            if (row.label === '项') {
                const listId = row.parentId
                const levelNodes = getItemOfTreeArr(this.tableData, 'listId', listId)
                levelNodes.forEach(item => {
                    item.price = ''
                    this.$set(this.mapTableData, item.listId, item)
                    // this.mapTableData[item.listId] = item
                })
            }
            // 计算当前行金额
            row.amount = Math.round(row.price * row.num)
            // 计算子金额（单价会改变子级）
            let temp = row.children
            while (temp) {
                temp.forEach(item => {
                    item.amount = Math.round(item.price * item.num)
                    this.$set(this.mapTableData, item.listId, item)
                    // this.mapTableData[item.listId] = item
                })
                temp = temp.children ? temp.children : null
            }
            // 向上汇总金额
            this.recurCount({
                parentId: row.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                row,
                str: 'amount'
            })
        },
        tenderListRule () {
            if (this.tableData.length === 0) {
                this.ruleMessage = '请添加清单'
                this.$emit('onChangeTab', { name: 'tenderListCon' })
                return false
            }
            const ruleMessageArr = new Set()
            // console.log('this.mapTableData', this.mapTableData)
            Object.values(this.mapTableData).forEach(item => {
                // 顶级不需要遍历
                if (!item.listId) return
                if (item.changeState === -1) return
                let name = item.code
                    ? '细目编号-' + item.code
                    : '结构部位名称-' + item.structureNamePaths
                if (name === '结构部位名称-undefined') {
                    name = '项'
                }
                // 项需要填写细目编号
                if (item.label === '项') {
                    if (!item.code) {
                        ruleMessageArr.add(`${name}请填写细目编号`)
                    }
                }
                // 项需要填写细目名称
                if (item.label === '项') {
                    if (!item.codeName) {
                        ruleMessageArr.add(`${name}请填写细目名称`)
                    }
                }
                // 清单最明细层要填单价类型（审核中不验证）
                if (item.isListLeaf === 1 && this.canAddDel) {
                    if (!item.priceType) {
                        ruleMessageArr.add(`${name}请选择单价类型`)
                    }
                }
                // 最明细级要填单价
                if (item.isLeaf === 1 && item.unit !== '总额') {
                    if (!item.price) {
                        ruleMessageArr.add(`${name}请填写单价`)
                    }
                }
                // 结构层要填数量
                if (item.structurePaths) {
                    if (item.num === '') {
                        ruleMessageArr.add(`${name}请填写数量`)
                    }
                }
            })
            this.ruleMessage = [...ruleMessageArr].join('，')
            if (this.ruleMessage !== '') {
                this.$emit('onChangeTab', { name: 'tenderListCon' })
                return false
            } else {
                // 验证小计
                if (this.ruleSubtotal(Object.values(this.mapTableData))) {
                    return true
                } else {
                    this.$emit('onChangeTab', { name: 'tenderListCon' })
                    return false
                }
            }
        },
        async save () {
            if (this.allMapTableData.length === 0) return Promise.resolve()
            // if (!this.tenderListRule()) {
            //     this.$emit('onChangeTab', { name: 'tenderList' })
            //     return Promise.reject()
            // }
            // new Promise(resolve => {
            // let num = 0
            // const length = this.detailsData.length
            // 保存数据不改变原table
            const temp = JSON.parse(JSON.stringify(this.allMapTableData))
            await Promise.all(
                temp.map(async item => {
                    if (item === null) return
                    const arrMap = Object.values(item)
                    // 在有结构部位时判断每个节点是否更新（补遗可能在watch做）
                    // 如果wholeListData没数据，说明是新增，没必要判断（过滤掉0级）
                    arrMap.forEach(item => {
                        const wholeListData = Object.values(this.wholeListData).filter(
                            item => item.listId
                        )
                        if (wholeListData.length !== 0) {
                            let initData = this.cloneMapInitTableData[item.listId]
                            let itemData = ''
                            // 0级或结构不比较
                            if (!item.listId || !item.label) return
                            initData =
                                JSON.stringify(initData?.code) +
                                JSON.stringify(initData?.codeName) +
                                JSON.stringify(initData?.priceType) +
                                JSON.stringify(initData?.num) +
                                JSON.stringify(initData?.price) +
                                JSON.stringify(initData?.lossRate) +
                                JSON.stringify(initData?.equipmentPrice) +
                                JSON.stringify(initData?.otherPrice) +
                                JSON.stringify(initData?.amount) +
                                JSON.stringify(initData?.rule)
                            itemData =
                                JSON.stringify(item?.code) +
                                JSON.stringify(item?.codeName) +
                                JSON.stringify(item?.priceType) +
                                JSON.stringify(item?.num) +
                                JSON.stringify(item?.price) +
                                JSON.stringify(item?.lossRate) +
                                JSON.stringify(item?.equipmentPrice) +
                                JSON.stringify(item?.otherPrice) +
                                JSON.stringify(item?.amount) +
                                JSON.stringify(item?.rule)
                            if (
                                initData &&
                                itemData !== initData &&
                                item.changeState !== -1 &&
                                item.changeState !== 1
                            ) {
                                // 判断金额、数量、单价是否修改
                                if (item.amount != this.cloneMapInitTableData[item.listId].amount) {
                                    item.isUpdateAmountState = true
                                } else {
                                    item.isUpdateAmountState = false
                                }
                                if (item.num != this.cloneMapInitTableData[item.listId].num) {
                                    item.isUpdateNumState = true
                                } else {
                                    item.isUpdateNumState = false
                                }
                                if (item.price != this.cloneMapInitTableData[item.listId].price) {
                                    item.isUpdatePriceState = true
                                } else {
                                    item.isUpdatePriceState = false
                                }
                                item.changeState = 2
                                // wholeListData也要做改变，已选数据需要
                                if (this.wholeListData[item.listId]) {
                                    this.wholeListData[item.listId].changeState = 2
                                }
                            }
                            // 如果有子级（只会有1级，因为arrMap包含所有节点）
                            if (item.children && item.children.length !== 0) {
                                console.log('item11', item)
                                item.children.forEach(item => {
                                    initData =
                                        String(initData.code) +
                                        String(initData.codeName) +
                                        String(initData.priceType) +
                                        String(initData.num) +
                                        String(initData.price) +
                                        String(initData.lossRate) +
                                        String(initData.equipmentPrice) +
                                        String(initData.otherPrice) +
                                        String(initData.amount) +
                                        String(initData.rule)
                                    itemData =
                                        String(item.code) +
                                        String(item.codeName) +
                                        String(item.priceType) +
                                        String(item.num) +
                                        String(item.price) +
                                        String(item.lossRate) +
                                        String(item.equipmentPrice) +
                                        String(item.otherPrice) +
                                        String(item.amount) +
                                        String(item.rule)
                                    if (
                                        initData &&
                                        itemData !== initData &&
                                        item.changeState !== -1 &&
                                        item.changeState !== 1
                                    ) {
                                        item.changeState = 2
                                        // wholeListData也要做改变，已选数据需要
                                        if (this.wholeListData[item.listId]) {
                                            this.wholeListData[item.listId].changeState = 2
                                        }
                                    }
                                })
                            }
                        }
                    })
                    // 去除结构部位
                    let res = arrMap.filter(item => item.label)
                    // 删除数据也要去除结构部位
                    // if (this.allDeleteTableData[index]) {
                    //     this.allDeleteTableData[index] = this.allDeleteTableData[index].filter(
                    //         item => item.label
                    //     )
                    // }
                    res.forEach(item => {
                        // 项的结构都是初始数据，需要替换成children
                        // if (item.label === '项') {
                        if (item.applyStructureList) {
                            item.applyStructureList = JSON.parse(JSON.stringify(item.children))
                        }
                        // 去除children
                        delete item.children
                        // 只有最子级有部位
                        if (item.isLeaf === 0) {
                            delete item.applyStructureList
                        }
                    })
                    // if (this.allDeleteTableData[index] === undefined) {
                    //     this.allDeleteTableData[index] = []
                    // }
                    // res = [...res, ...this.allDeleteTableData[index]]
                    // mapData可能和deleteData重复
                    // let filterArr = []
                    // res = res.filter(item => {
                    //     if (filterArr.includes(item.listId)) return false
                    //     filterArr.push(item.listId)
                    //     return true
                    // })
                    // const mapStartEndStake = {}
                    // res.forEach(item => {
                    //     // applyStructureList给deleteState初始值
                    //     if (item.applyStructureList) {
                    //         item.applyStructureList.forEach(item => {
                    //             item.deleteState = item.deleteState ? item.deleteState : 0
                    //             mapStartEndStake[item.billId] = item
                    //         })
                    //     }
                    // })
                    // const startEndStakeStr = Object.values(mapStartEndStake)
                    //     .map(item => item.structureNamePaths)
                    //     .join(',')
                    // this.$emit('startEndStake', startEndStakeStr, index)
                    if (Object.keys(this.mapTableData).length !== 0) {
                        // this.setSelectedInfo(res)
                        // openAppClient('/showSelectedData', '选择结果', function () {})
                        console.log('res', res)
                        await tenderRequest.crateLaborDtl(res)
                    }
                    // num++
                    // if (num === length) {
                    //     resolve()
                    // }
                })
            ).then(() => {
                // this.cloneTableData = []
                this.mapTableData = {}
                // // this.deleteTableData = []
                // this.addList = []
                // this.allTableData = []
                // this.allMapTableData = []
                // // this.allDeleteTableData = []
                this.cloneMapInitTableData = {}
                this.tableData = []
                if (this.dtlId) {
                    this.getData()
                    this.getAllData()
                }
            })
            // })
        },
        // 生成结构部位
        async addStructure (row, parentId) {
            // 结构的初始数据
            const temp = JSON.parse(JSON.stringify(row.applyStructureList))
            const uid = await this.uidBuilder({ num: temp.length }, 'arr')
            if (row.children[0].label !== '项') {
                console.log('子不是项')
                temp.forEach((item, index) => {
                    item.listId = uid[index]
                    item.parentId = parentId
                    item.price = row.price
                    item.num = row.num
                    this.$set(this.mapTableData, item.listId, item)
                    // this.mapTableData[item.listId] = item
                })
            } else {
                console.log('子是项')
                temp.forEach((item, index) => {
                    item.listId = uid[index]
                    item.parentId = parentId
                    item.price = 0
                    item.num = 0
                    this.$set(this.mapTableData, item.listId, item)
                    // this.mapTableData[item.listId] = item
                })
            }
            return temp
        },
        // 导入后的changeState
        importChangeState (item) {
            const wholeListDataArr = Object.values(this.wholeListData)
            // 如果wholeListData长度为0，说明是第1次引入数据，为新增1
            if (wholeListDataArr.length === 0) {
                return 1
            } else {
                // 如果wholeListData没有的id，表示新增
                if (!this.wholeListData[item.thisLevelId]) {
                    return 1
                } else {
                    // 如果wholeListData的changeState是2
                    if (this.wholeListData[item.thisLevelId].changeState === 2) {
                        return 2
                    } else {
                        return 0
                    }
                }
            }
        },
        // 后端需要的字段
        arrFieldConvert (arr, cloneMapTableData) {
            console.log('arr0', arr)
            const res = []
            //  Promise.all(
            arr.map((item, index) => {
                // console.log('item0', item)
                // 后端要的格式
                res.push({
                    amount: 0,
                    applyStructureList: item.structure.length !== 0 ? item.structure : [],
                    billId: this.tenderId,
                    changeState: this.importChangeState(item),
                    code: '', // 细目编码
                    codeName: '', // 细目名称
                    isAllLeaf: 0, // 是否所有最子级（结构）
                    isLeaf: 0, // 是否最明细
                    isListLeaf: 0, // 是否是清单最子级
                    isUpdateAmountState: false,
                    isUpdateNumState: false,
                    isUpdatePriceState: false,
                    label: '', // 标识
                    listId: '', // 本级id
                    num: 0, // 数量
                    packageId: this.dtlId,
                    parentId: '', // 	父级ID
                    price: '',
                    priceType: '',
                    // recordId: '',
                    unit: '', // 计量单位
                    lossRate: 0, // 损耗率
                    materialPrice: 0, // 甲供材料单价
                    materialPriceLoss: 0, // 甲供材料单价（损耗）
                    otherPrice: 0, // 甲供其他单价
                    rule: '', // 计量规则、计价规则
                    equipmentPrice: 0, // 甲供设备单价
                    subtotal: 0, // 小计
                    budgetPrice: 0, // 预算综合单价
                    targetBudgetListId: '', // 目标预算清单id
                    uuid: ''
                })
                // 处理成后端要的结构数据
                if (res[index].applyStructureList.length === 0) {
                    delete res[index].applyStructureList
                } else {
                    // const uid = await this.uidBuilder(
                    //     {
                    //         num: res[index].applyStructureList.length
                    //     },
                    //     'arr'
                    // )
                    res[index].applyStructureList.forEach(item => {
                        item.listId = item.thisLevelId
                        item.num = item.quantity
                        item.price = 0
                        item.amount = 0
                        item.deleteState = 0
                        delete item.isDetailed
                        delete item.structureName
                        delete item.thisLevelId
                        delete item.quantity
                    })
                }
                // 将客户端数据带给后端格式数据
                res[index].label = item.identification
                res[index].isListLeaf = item.termIsDetailed || 0
                res[index].isAllLeaf = 0
                res[index].isLeaf = item.isDetailed
                res[index].codeName = item.itemName
                res[index].code = item.itemNo
                res[index].parentId = item.parentId
                res[index].num = item.quantity
                res[index].unit = item.unit
                res[index].listId = item.thisLevelId
                res[index].uuid = item.uuid
                res[index].targetBudgetListId = item.billId
                res[index].materialPrice = item.materialPrice || 0 // 甲供设备单价，先假设个数字，没返应该默认为空字符串
                res[index].budgetPrice = item.budgetPrice || 0 // 预算单价
                // console.log('item.quantity', item.quantity)
                // console.log('res[index].num ', res[index].num )
                // console.log('res', res)
                // console.log('res[index]', res[index])
                // 初始计算招标限价
                const row = res[index]
                // 甲供材料（含损耗）单价
                row.materialPriceLoss = parseFloat(
                    (row.materialPrice * (1 + row.lossRate / 100)).toFixed(2)
                )
                // 小计
                // row.subtotal =
                //     (parseFloat(row.price) || 0) +
                //     (parseFloat(row.materialPriceLoss) || 0) +
                //     (parseFloat(row.equipmentPrice) || 0) +
                //     (parseFloat(row.otherPrice) || 0)
                // 11.2修改需求
                // 小计则用甲供材料单价计算
                row.subtotal = parseFloat(row.materialPrice)
                const mapStartEndStake = {}
                res.forEach(item => {
                    // applyStructureList给deleteState初始值
                    if (item.applyStructureList) {
                        item.applyStructureList.forEach(item => {
                            item.deleteState = item.deleteState ? item.deleteState : 0
                            mapStartEndStake[item.billId] = item
                        })
                    }
                })
                const startEndStakeStr = Object.values(mapStartEndStake)
                    .map(item => item.structureNamePaths)
                    .join(',')
                this.$emit('startEndStake', startEndStakeStr, this.dtlIndex)
            })
            // 选择的数据对比之前数据，如果有还是使用之前数据
            if (cloneMapTableData !== undefined) {
                res.forEach((item, index) => {
                    if (cloneMapTableData[item.listId]) {
                        res[index].code = cloneMapTableData[item.listId].code
                        res[index].codeName = cloneMapTableData[item.listId].codeName
                        res[index].structureNamePaths =
                            cloneMapTableData[item.listId].structureNamePaths
                        res[index].unit = cloneMapTableData[item.listId].unit
                        res[index].priceType = cloneMapTableData[item.listId].priceType
                        res[index].num = cloneMapTableData[item.listId].num
                        res[index].price = cloneMapTableData[item.listId].price
                        res[index].materialPrice = cloneMapTableData[item.listId].materialPrice
                        res[index].lossRate = cloneMapTableData[item.listId].lossRate
                        res[index].materialPriceLoss =
                            cloneMapTableData[item.listId].materialPriceLoss
                        res[index].equipmentPrice = cloneMapTableData[item.listId].equipmentPrice
                        res[index].otherPrice = cloneMapTableData[item.listId].otherPrice
                        res[index].subtotal = cloneMapTableData[item.listId].subtotal
                        res[index].amount = cloneMapTableData[item.listId].amount
                        res[index].rule = cloneMapTableData[item.listId].rule
                        // if(item.applyStructureList) {
                        //     item.applyStructureList.forEach(item=>{
                        //         item.amount = cloneMapTableData[item.listId].amount
                        //     })
                        // }
                    }
                })
            }
            // 如果选择的数据没有则是删除
            // eslint-disable-next-line no-debugger
            // debugger
            // Object.keys(this.mapTableData).forEach(item2 => {
            //     if (item2 === '0') return
            //     const temp = res.find(item3 => item3.listId !== item2)
            //     console.log('this.mapTableData[temp.listId]', this.mapTableData[temp.listId])
            //     this.mapTableData[temp.listId].changeState = -1
            // })
            return res
        },
        //  审核时验证：标识为“清单”的最子级细目的招标限价小计不能超预算综合单价
        ruleSubtotal (mapTableData) {
            const err = []
            mapTableData.forEach(item => {
                if (item.subtotal > item.budgetPrice) {
                    err.push(`细目编号${item.code}小计不能超过预算综合单价${item.budgetPrice}`)
                }
            })
            this.ruleMessage = err.join('，')
            if (this.ruleMessage !== '') {
                return false
            } else {
                return true
            }
        },
        // 数组转树
        arrToTree (arr) {
            const rootId = arr[0].parentId
            const res = []
            const map = arr.reduce((res, v) => ((res[v.listId] = v), res), {})
            for (const item of arr) {
                // 添加结构
                if (item.applyStructureList) {
                    item.children = JSON.parse(JSON.stringify(item.applyStructureList))
                }
                if (item.parentId === rootId) {
                    res.push(item)
                    continue
                }
                if (item.parentId in map) {
                    const parent = map[item.parentId]
                    parent.children = parent.children || []
                    parent.children.push(item)
                }
            }
            return res
        },
        // 树转数组
        treeToArr (tree) {
            return tree.reduce(
                (arr, { id, title, pid, children = [] }) =>
                    arr.concat([{ id, title, pid }], this.treeToArr(children)),
                []
            )
        },
        // 获取包件列表数据
        async findByApplyId () {
            let data = []
            let leftTree = []
            if (this.detailsOfProposed.length !== 0) {
                data = this.detailsOfProposed
            } else {
                await applyRequest.bidPackageListByBillId(this.tenderId).then(res => {
                    data = res
                })
            }
            data.forEach(value => {
                leftTree.push({ label: value.name })
            })
            this.detailsOfProposedArr = leftTree
        },
        // 通过id获取子级数据
        async getById (listId) {
            // （此处为模拟）
            const uid = await this.uidBuilder({ num: 2 })
            // 右侧树列表假数据
            const result = [
                {
                    recordId: '', //记录ID
                    packageId: '123', //包件ID
                    parentId: listId, //父级ID
                    code: uid[0], //细目编码
                    codeName: '123', //细目名称
                    isLeaf: 0, //是否是最明细级
                    hasChildren: true,
                    listId: uid[0], //本级ID
                    subitemName: '123', //分部分项名称
                    subitemId: '123', //分部分项ID
                    budgetName: '123', //预算名称
                    budgetId: '123', //预算id
                    unit: '123', //计量单位
                    num: 123, //数量 默认值为零
                    price: 123, //单价 默认值为零
                    priceType: '123', //单价类型 (劳务单价 全单价) 工程招标特有
                    amount: 123, //金额
                    billId: this.tenderId, //单据Id
                    label: 0, //标识(0,清单，1项，2结构部位)"
                    changeState: 1 //清单变更状态 0未变更 1新增 2编辑 -1删除
                },
                {
                    recordId: '', //记录ID
                    packageId: '123', //包件ID
                    parentId: listId, //父级ID
                    code: uid[1], //细目编码
                    codeName: '123', //细目名称
                    isLeaf: 0, //是否是最明细级
                    hasChildren: true,
                    listId: uid[1], //本级ID
                    subitemName: '123', //分部分项名称
                    subitemId: '123', //分部分项ID
                    budgetName: '123', //预算名称
                    budgetId: '123', //预算id
                    unit: '123', //计量单位
                    num: 123, //数量 默认值为零
                    price: 123, //单价 默认值为零
                    priceType: '123', //单价类型 (劳务单价 全单价) 工程招标特有
                    amount: 123, //金额
                    billId: this.tenderId, //单据Id
                    label: 0, //标识(0,清单，1项，2结构部位)"
                    changeState: 1 //清单变更状态 0未变更 1新增 2编辑 -1删除
                }
            ]
            return result
        },
        saveMapTableData (temp = this.tableData, clone = false) {
            if (temp === null) return
            this.$set(this.mapTableData, '0', {
                children: this.tableData
            })
            // this.mapTableData['0'] = {
            //     children: this.tableData
            // }
            temp.forEach(item => {
                while (item) {
                    if (item.listId === undefined) break
                    this.$set(this.mapTableData, item.listId, item)
                    if (clone) {
                        this.saveCloneMap(item)
                    }
                    // this.mapTableData[item.listId] = item
                    item = item.children ? item.children : null
                    this.saveMapTableData(item, clone)
                }
            })
        },
        // 结构层转换客户端要的数据
        structureConver (applyStructureList) {
            const temp = []
            applyStructureList.forEach((item, index) => {
                temp.push({
                    billId: '',
                    budgetPrice: 0,
                    identification: null,
                    isDetailed: null,
                    itemName: null,
                    itemNo: null,
                    materialPrice: 0,
                    parentId: '',
                    quantity: 0,
                    structureName: '',
                    structureNamePaths: '',
                    structurePaths: '',
                    termIsDetailed: null,
                    thisLevelId: '',
                    unit: null,
                    structure: null
                })
                temp[index].billId = item.targetBudgetListId || null
                temp[index].budgetPrice = item.budgetPrice || null
                temp[index].identification = item.label || null
                temp[index].isDetailed = item.isLeaf || null
                temp[index].itemName = item.codeName || null
                temp[index].itemNo = item.code || null
                temp[index].materialPrice = item.materialPrice || null
                temp[index].parentId = item.parentId || null
                temp[index].quantity = item.num || null
                temp[index].structureName = item.structureName || null
                temp[index].structureNamePaths = item.structureNamePaths || null
                temp[index].structurePaths = item.structurePaths || null
                temp[index].termIsDetailed = item.isListLeaf || null
                temp[index].thisLevelId = item.listId || null
                temp[index].unit = item.unit || null
            })
            return temp
        },
        // 后端数据转成客户端要的数据
        arrFieldConvert2 (selectedData) {
            console.log('selectedData', selectedData)
            if (selectedData.length === 0) return []
            let temp = []
            selectedData.forEach((item, index) => {
                temp.push({
                    billId: '',
                    budgetPrice: null,
                    identification: '',
                    isDetailed: 0,
                    itemName: '',
                    itemNo: '',
                    materialPrice: null,
                    parentId: '',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '',
                    unit: '',
                    structure: []
                })
                temp[index].billId = item.targetBudgetListId || null
                temp[index].budgetPrice = item.budgetPrice || null
                temp[index].identification = item.label || null
                temp[index].isDetailed = item.isLeaf || 0
                temp[index].itemName = item.codeName || null
                temp[index].itemNo = item.code || null
                temp[index].materialPrice = item.materialPrice || null
                temp[index].parentId = item.parentId || null
                temp[index].quantity = item.num || null
                temp[index].structureName = item.structureName || null
                temp[index].structureNamePaths = item.structureNamePaths || null
                temp[index].structurePaths = item.structurePaths || null
                temp[index].termIsDetailed = item.isListLeaf || 0
                temp[index].thisLevelId = item.listId || null
                temp[index].unit = item.unit || null
                temp[index].structure = item.applyStructureList
                    ? this.structureConver(item.applyStructureList)
                    : []
            })
            // 过滤掉0级    // 过滤掉结构（已包含在最子集清单里）
            temp = temp.filter(item => item.thisLevelId && item.identification)
            return temp
        },
        // 已选数据传给客户端返显（懒加载的数据才需要这个方法处理）
        getSelectedData () {
            if (Object.keys(this.mapTableData).length === 0) return []
            const selectedData = []
            Object.keys(this.mapTableData).forEach(item => {
                // 第一级
                if (item === '0') {
                    this.mapTableData[0].children.forEach(item => {
                        selectedData.push(item)
                    })
                    // 后面级
                } else {
                    selectedData.push(this.mapTableData[item])
                }
            })
            return selectedData
        },
        // 获取已选节点
        getSelectedIDs () {
            const wholeListDataArr = Object.values(this.wholeListData)
            const mapTableDataArr = Object.values(this.mapTableData)
            if (wholeListDataArr.length === 0) {
                // 如果mapTable为-1，代表删掉了，应该去掉
                for (let i = 0; i < mapTableDataArr.length; i++) {
                    const item = mapTableDataArr[i]
                    const changeState = this.mapTableData[item.listId]?.changeState // 0级没listId
                    if (changeState === -1) {
                        mapTableDataArr.splice(i--, 1)
                    }
                }
                return this.arrFieldConvert2(mapTableDataArr)
            } else {
                // 如果wholeListData为-1，代表删掉了，应该去掉
                for (let i = 0; i < wholeListDataArr.length; i++) {
                    const item = wholeListDataArr[i]
                    const changeState = this.wholeListData[item.listId]?.changeState // 0级没listId
                    if (changeState === -1) {
                        wholeListDataArr.splice(i--, 1)
                    }
                }
                return this.arrFieldConvert2(wholeListDataArr)
            }
        },
        importList () {
            if (this.dtlId === '') {
                this.clientPop('err', '请先添加包件')
                return
            }
            // 获取已选节点
            const SelectedIDs = this.getSelectedIDs()
            console.log('SelectedIDs', SelectedIDs)
            // this.setSelectedInfo(SelectedIDs)
            // openAppClient('/showSelectedData', 'SelectedIDs', function () {})
            selectDataClient({
                SelectServiceToken: 'EngineerSelectorImportDetail', // 客户端对应方法名
                IsSingleMode: false, // 是否单选 true 单选 false 多选
                SelectedIDs: [], // 已选中id
                // InitParamsStr: JSON.stringify(selectedData), //初始化参数
                InitParamsStr: JSON.stringify(SelectedIDs),
                Title: '选择清单' // 标题
            }).then(async val => {
                // this.setSelectedInfo(val)
                // openAppClient('/showSelectedData', '选择结果', function () {})
                // 备份一个对比选择数据是否包含已有数据
                const cloneMapTableData = JSON.parse(JSON.stringify(this.mapTableData))
                //  如果没选数据
                if (val.length === 0) {
                    // 重置
                    this.cloneTableData = []
                    this.mapTableData = {}
                    this.deleteTableData = []
                    this.addList = []
                    this.cloneMapInitTableData = {}
                    this.tableData = []
                    return
                }
                // 处理客户端重复数据
                val = this.backEndBug(val)
                // this.setSelectedInfo(val)
                // openAppClient('/showSelectedData', '选择结果', function () {})
                // 转换前端显示数据
                // arrFieldConvert changeState会在此时定义
                await this.$emit(
                    'change',
                    this.arrToTree(this.arrFieldConvert(val, cloneMapTableData))
                )
                // 重置table，不然table展开时数据不刷新
                this.tableRefState = false
                setTimeout(() => {
                    this.tableRefState = true
                }, 0)
                this.saveMapTableData()
                // saveMapTableData会使changeState -1还原0，找不到原因
                // const tempArr = Object.keys(this.mapTableData).filter(item=>item != '0')
                // if(tempArr.length === 0) return
                // console.log('tempArr', tempArr)
                const valListId = val.map(item => item.thisLevelId)
                Object.keys(this.mapTableData).forEach(item2 => {
                    if (item2 === '0') return
                    const temp = valListId.includes(item2)
                    if (temp === false) {
                        // if(this.mapTableData[item2].changeState !== 1) {
                        this.mapTableData[item2].changeState = -1
                        // }
                    }
                })
                // 用来对比的初始数据
                // const temp = this.arrFieldConvert(val)
                // temp.forEach(item => {
                //     this.saveCloneMap(item)
                // })
                // 做完对比再置空
                this.wholeListData = {}
                // 初始化计算数量
                // this.initCalNum('num')
            })
        },
        // 100章-101-1-a
        async importList2 () {
            if (this.dtlId === '') {
                this.clientPop('err', '请先添加包件')
                return
            }
            // 测试数据1
            var val = [
                {
                    billId: '1562837339008004240',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '路面',
                    itemNo: '300章',
                    materialPrice: null,
                    parentId: '0',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '7755ec6a719669b56e0c4b44212afeb7',
                    unit: '',
                    structure: []
                },
                {
                    billId: '1562837339008004241',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '碎石垫层',
                    itemNo: '302-1',
                    materialPrice: null,
                    parentId: '7755ec6a719669b56e0c4b44212afeb7',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '4be121fc76a4e60078ed70b957d13377',
                    unit: 'm2',
                    structure: []
                },
                {
                    billId: '1562837339008004242',
                    budgetPrice: 10,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '厚15cm',
                    itemNo: '302-1-a',
                    materialPrice: null,
                    parentId: '4be121fc76a4e60078ed70b957d13377',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '5fd05f8a40291eabacfef9666d644aac',
                    unit: 'm2',
                    structure: [
                        {
                            billId: '1567804546046685187',
                            budgetPrice: 10,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '5fd05f8a40291eabacfef9666d644aac',
                            quantity: 10,
                            structureName: '碎石垫层',
                            structureNamePaths: '路面-垫层-碎石垫层',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"2a03bb598d4b42078ab9d6bf5369cb59","parentId":"0","structureId":"1567804546046685185","structureName":"路面","structureNo":"3","structureType":0},{"isLeaf":0,"listId":"d369203eaebe4786a5ebfe00593ca06a","parentId":"2a03bb598d4b42078ab9d6bf5369cb59","structureId":"1567804546046685186","structureName":"垫层","structureNo":"3-1","structureType":0},{"isLeaf":1,"listId":"d784e729ade742b4bc3b59590e2836ec","parentId":"d369203eaebe4786a5ebfe00593ca06a","structureId":"1567804546046685187","structureName":"碎石垫层","structureNo":"3-1-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205658820440066',
                            unit: null,
                            structure: null
                        }
                    ]
                }
            ]
            // 备份一个对比选择数据是否包含已有数据
            const cloneMapTableData = JSON.parse(JSON.stringify(this.mapTableData))
            //  如果没选数据
            if (val.length === 0) {
                // 重置
                this.cloneTableData = []
                this.mapTableData = {}
                this.deleteTableData = []
                this.addList = []
                this.cloneMapInitTableData = {}
                this.tableData = []
                return
            }
            // 处理客户端重复数据
            val = this.backEndBug(val)
            // this.setSelectedInfo(val)
            // openAppClient('/showSelectedData', '选择结果', function () {})
            // 转换前端显示数据
            // arrFieldConvert changeState会在此时定义
            await this.$emit('change', this.arrToTree(this.arrFieldConvert(val, cloneMapTableData)))
            // 重置table，不然table展开时数据不刷新
            this.tableRefState = false
            setTimeout(() => {
                this.tableRefState = true
            }, 0)
            this.saveMapTableData()
            // saveMapTableData会使changeState -1还原0，找不到原因
            // const tempArr = Object.keys(this.mapTableData).filter(item=>item != '0')
            // if(tempArr.length === 0) return
            // console.log('tempArr', tempArr)
            const valListId = val.map(item => item.thisLevelId)
            console.clear()
            console.log('val', val)
            console.log('valListId', valListId)
            console.log('this.mapTableData', this.mapTableData)
            Object.keys(this.mapTableData).forEach(item2 => {
                if (item2 === '0') return
                const temp = valListId.includes(item2)
                if (temp === false) {
                    // if(this.mapTableData[item2].changeState !== 1) {
                    this.mapTableData[item2].changeState = -1
                    // }
                }
            })
            // 用来对比的初始数据
            // const temp = this.arrFieldConvert(val)
            // temp.forEach(item => {
            //     this.saveCloneMap(item)
            // })
            // 做完对比再置空
            this.wholeListData = {}
            // 初始化计算数量
            // this.initCalNum('num')
        },
        // 100章-101-1-b
        async importList3 () {
            if (this.dtlId === '') {
                this.clientPop('err', '请先添加包件')
                return
            }
            // 测试数据1
            var val = [
                {
                    billId: '1562837339008004240',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '路面',
                    itemNo: '300章',
                    materialPrice: null,
                    parentId: '0',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '7755ec6a719669b56e0c4b44212afeb7',
                    unit: null,
                    structure: []
                },
                {
                    billId: '1562837339008004241',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '碎石垫层',
                    itemNo: '302-1',
                    materialPrice: null,
                    parentId: '7755ec6a719669b56e0c4b44212afeb7',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '4be121fc76a4e60078ed70b957d13377',
                    unit: 'm2',
                    structure: []
                },
                {
                    billId: '1562837339008004242',
                    budgetPrice: 10,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '厚15cm',
                    itemNo: '302-1-a',
                    materialPrice: null,
                    parentId: '4be121fc76a4e60078ed70b957d13377',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '5fd05f8a40291eabacfef9666d644aac',
                    unit: 'm2',
                    structure: [
                        {
                            billId: null,
                            budgetPrice: 10,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '5fd05f8a40291eabacfef9666d644aac',
                            quantity: 10,
                            structureName: null,
                            structureNamePaths: '路面-垫层-碎石垫层',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"2a03bb598d4b42078ab9d6bf5369cb59","parentId":"0","structureId":"1567804546046685185","structureName":"路面","structureNo":"3","structureType":0},{"isLeaf":0,"listId":"d369203eaebe4786a5ebfe00593ca06a","parentId":"2a03bb598d4b42078ab9d6bf5369cb59","structureId":"1567804546046685186","structureName":"垫层","structureNo":"3-1","structureType":0},{"isLeaf":1,"listId":"d784e729ade742b4bc3b59590e2836ec","parentId":"d369203eaebe4786a5ebfe00593ca06a","structureId":"1567804546046685187","structureName":"碎石垫层","structureNo":"3-1-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205658820440066',
                            unit: null,
                            structure: null
                        }
                    ]
                },
                {
                    billId: '1562837339008004500',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '桥梁、涵洞',
                    itemNo: '400章',
                    materialPrice: null,
                    parentId: '0',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '6f716918608b29b90a18af90843549ee',
                    unit: '',
                    structure: []
                },
                {
                    billId: '1562837339008004794',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '下部结构钢筋',
                    itemNo: '403-2',
                    materialPrice: null,
                    parentId: '6f716918608b29b90a18af90843549ee',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '1907b26f0fd9924a8fe28c844fb3338e',
                    unit: 'kg',
                    structure: []
                },
                {
                    billId: '1562837339008004795',
                    budgetPrice: 10,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '光圆钢筋（HPB235、HPB300）',
                    itemNo: '403-2-a',
                    materialPrice: null,
                    parentId: '1907b26f0fd9924a8fe28c844fb3338e',
                    quantity: 100,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: 'b49545881447cfac886c26a636ee7f82',
                    unit: 'kg',
                    structure: [
                        {
                            billId: '1567804727290949636',
                            budgetPrice: 10,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: 'b49545881447cfac886c26a636ee7f82',
                            quantity: 100,
                            structureName: '圆墩',
                            structureNamePaths: '桥梁、涵洞-下部构造-桥墩-圆墩',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"086f34f9bc7446a29a5aa4660e099a44","parentId":"0","structureId":"1567804727290949633","structureName":"桥梁、涵洞","structureNo":"4","structureType":0},{"isLeaf":0,"listId":"58604bdca9274929a370ae9c65c79b41","parentId":"086f34f9bc7446a29a5aa4660e099a44","structureId":"1567804727290949634","structureName":"下部构造","structureNo":"4-3","structureType":0},{"isLeaf":0,"listId":"dc6596819f594d31a8851819b1733de9","parentId":"58604bdca9274929a370ae9c65c79b41","structureId":"1567804727290949635","structureName":"桥墩","structureNo":"4-3-2","structureType":0},{"isLeaf":1,"listId":"4e4c166baf6d45dfbd772597db08ec36","parentId":"dc6596819f594d31a8851819b1733de9","structureId":"1567804727290949636","structureName":"圆墩","structureNo":"4-3-2-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205772548993025',
                            unit: null,
                            structure: null
                        }
                    ]
                },
                {
                    billId: '1562837339008004797',
                    budgetPrice: 100,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '带肋钢筋（HRB335、HRB400）',
                    itemNo: '403-2-b',
                    materialPrice: null,
                    parentId: '1907b26f0fd9924a8fe28c844fb3338e',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '20ea07deae3123bde82170ddd1e22c78',
                    unit: 'kg',
                    structure: [
                        {
                            billId: '1567804727290949636',
                            budgetPrice: 100,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '20ea07deae3123bde82170ddd1e22c78',
                            quantity: 10,
                            structureName: '圆墩',
                            structureNamePaths: '桥梁、涵洞-下部构造-桥墩-圆墩',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"086f34f9bc7446a29a5aa4660e099a44","parentId":"0","structureId":"1567804727290949633","structureName":"桥梁、涵洞","structureNo":"4","structureType":0},{"isLeaf":0,"listId":"58604bdca9274929a370ae9c65c79b41","parentId":"086f34f9bc7446a29a5aa4660e099a44","structureId":"1567804727290949634","structureName":"下部构造","structureNo":"4-3","structureType":0},{"isLeaf":0,"listId":"dc6596819f594d31a8851819b1733de9","parentId":"58604bdca9274929a370ae9c65c79b41","structureId":"1567804727290949635","structureName":"桥墩","structureNo":"4-3-2","structureType":0},{"isLeaf":1,"listId":"4e4c166baf6d45dfbd772597db08ec36","parentId":"dc6596819f594d31a8851819b1733de9","structureId":"1567804727290949636","structureName":"圆墩","structureNo":"4-3-2-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205772557381633',
                            unit: null,
                            structure: null
                        }
                    ]
                },
                {
                    billId: '1562837339008004811',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '桥墩混凝土',
                    itemNo: '410-2-b',
                    materialPrice: null,
                    parentId: '6f716918608b29b90a18af90843549ee',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: 'ca8aeeacfeb370fdcaa05dd7b0d5caf2',
                    unit: 'm³',
                    structure: []
                },
                {
                    billId: '1562837339008004812',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '圆墩',
                    itemNo: '410-2-b-1',
                    materialPrice: null,
                    parentId: 'ca8aeeacfeb370fdcaa05dd7b0d5caf2',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '8aa999c809da0f37cd24ab055e3f6b78',
                    unit: 'm³',
                    structure: []
                },
                {
                    billId: '1562837339008004813',
                    budgetPrice: 200,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: 'C30混凝土',
                    itemNo: '410-2-b-1-1',
                    materialPrice: null,
                    parentId: '8aa999c809da0f37cd24ab055e3f6b78',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '98a745118fcf0697fe01341762eb45df',
                    unit: 'm³',
                    structure: [
                        {
                            billId: '1567804727290949636',
                            budgetPrice: 200,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '98a745118fcf0697fe01341762eb45df',
                            quantity: 10,
                            structureName: '圆墩',
                            structureNamePaths: '桥梁、涵洞-下部构造-桥墩-圆墩',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"086f34f9bc7446a29a5aa4660e099a44","parentId":"0","structureId":"1567804727290949633","structureName":"桥梁、涵洞","structureNo":"4","structureType":0},{"isLeaf":0,"listId":"58604bdca9274929a370ae9c65c79b41","parentId":"086f34f9bc7446a29a5aa4660e099a44","structureId":"1567804727290949634","structureName":"下部构造","structureNo":"4-3","structureType":0},{"isLeaf":0,"listId":"dc6596819f594d31a8851819b1733de9","parentId":"58604bdca9274929a370ae9c65c79b41","structureId":"1567804727290949635","structureName":"桥墩","structureNo":"4-3-2","structureType":0},{"isLeaf":1,"listId":"4e4c166baf6d45dfbd772597db08ec36","parentId":"dc6596819f594d31a8851819b1733de9","structureId":"1567804727290949636","structureName":"圆墩","structureNo":"4-3-2-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205772561575937',
                            unit: null,
                            structure: null
                        }
                    ]
                }
            ]
            // 备份一个对比选择数据是否包含已有数据
            const cloneMapTableData = JSON.parse(JSON.stringify(this.mapTableData))
            //  如果没选数据
            if (val.length === 0) {
                // 重置
                this.cloneTableData = []
                this.mapTableData = {}
                this.deleteTableData = []
                this.addList = []
                this.cloneMapInitTableData = {}
                this.tableData = []
                return
            }
            // 处理客户端重复数据
            val = this.backEndBug(val)
            // this.setSelectedInfo(val)
            // openAppClient('/showSelectedData', '选择结果', function () {})
            // 转换前端显示数据
            // arrFieldConvert changeState会在此时定义
            await this.$emit('change', this.arrToTree(this.arrFieldConvert(val, cloneMapTableData)))
            // 重置table，不然table展开时数据不刷新
            this.tableRefState = false
            setTimeout(() => {
                this.tableRefState = true
            }, 0)
            this.saveMapTableData()
            // saveMapTableData会使changeState -1还原0，找不到原因
            // const tempArr = Object.keys(this.mapTableData).filter(item=>item != '0')
            // if(tempArr.length === 0) return
            // console.log('tempArr', tempArr)
            const valListId = val.map(item => item.thisLevelId)
            Object.keys(this.mapTableData).forEach(item2 => {
                if (item2 === '0') return
                const temp = valListId.includes(item2)
                if (temp === false) {
                    // if(this.mapTableData[item2].changeState !== 1) {
                    this.mapTableData[item2].changeState = -1
                    // }
                }
            })
            // 用来对比的初始数据
            // const temp = this.arrFieldConvert(val)
            // temp.forEach(item => {
            //     this.saveCloneMap(item)
            // })
            // 做完对比再置空
            this.wholeListData = {}
            // 初始化计算数量
            // this.initCalNum('num')
        },
        async importList4 () {
            if (this.dtlId === '') {
                this.clientPop('err', '请先添加包件')
                return
            }
            // 测试数据1
            var val = [
                {
                    billId: '1562837339008004240',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '路面',
                    itemNo: '300章',
                    materialPrice: null,
                    parentId: '0',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '7755ec6a719669b56e0c4b44212afeb7',
                    unit: null,
                    structure: []
                },
                {
                    billId: '1562837339008004241',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '碎石垫层',
                    itemNo: '302-1',
                    materialPrice: null,
                    parentId: '7755ec6a719669b56e0c4b44212afeb7',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '4be121fc76a4e60078ed70b957d13377',
                    unit: 'm2',
                    structure: []
                },
                {
                    billId: '1562837339008004242',
                    budgetPrice: 10,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '厚15cm',
                    itemNo: '302-1-a',
                    materialPrice: null,
                    parentId: '4be121fc76a4e60078ed70b957d13377',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '5fd05f8a40291eabacfef9666d644aac',
                    unit: 'm2',
                    structure: [
                        {
                            billId: null,
                            budgetPrice: 10,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '5fd05f8a40291eabacfef9666d644aac',
                            quantity: 10,
                            structureName: null,
                            structureNamePaths: '路面-垫层-碎石垫层',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"2a03bb598d4b42078ab9d6bf5369cb59","parentId":"0","structureId":"1567804546046685185","structureName":"路面","structureNo":"3","structureType":0},{"isLeaf":0,"listId":"d369203eaebe4786a5ebfe00593ca06a","parentId":"2a03bb598d4b42078ab9d6bf5369cb59","structureId":"1567804546046685186","structureName":"垫层","structureNo":"3-1","structureType":0},{"isLeaf":1,"listId":"d784e729ade742b4bc3b59590e2836ec","parentId":"d369203eaebe4786a5ebfe00593ca06a","structureId":"1567804546046685187","structureName":"碎石垫层","structureNo":"3-1-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '1582205658820440066',
                            unit: null,
                            structure: null
                        }
                    ]
                }
            ]
            // 备份一个对比选择数据是否包含已有数据
            const cloneMapTableData = JSON.parse(JSON.stringify(this.mapTableData))
            //  如果没选数据
            if (val.length === 0) {
                // 重置
                this.cloneTableData = []
                this.mapTableData = {}
                this.deleteTableData = []
                this.addList = []
                this.cloneMapInitTableData = {}
                this.tableData = []
                return
            }
            // 处理客户端重复数据
            val = this.backEndBug(val)
            // this.setSelectedInfo(val)
            // openAppClient('/showSelectedData', '选择结果', function () {})
            // 转换前端显示数据
            // arrFieldConvert changeState会在此时定义
            await this.$emit('change', this.arrToTree(this.arrFieldConvert(val, cloneMapTableData)))
            // 重置table，不然table展开时数据不刷新
            this.tableRefState = false
            setTimeout(() => {
                this.tableRefState = true
            }, 0)
            this.saveMapTableData()
            // saveMapTableData会使changeState -1还原0，找不到原因
            // const tempArr = Object.keys(this.mapTableData).filter(item=>item != '0')
            // if(tempArr.length === 0) return
            // console.log('tempArr', tempArr)
            const valListId = val.map(item => item.thisLevelId)
            Object.keys(this.mapTableData).forEach(item2 => {
                if (item2 === '0') return
                const temp = valListId.includes(item2)
                if (temp === false) {
                    // if(this.mapTableData[item2].changeState !== 1) {
                    this.mapTableData[item2].changeState = -1
                    // }
                }
            })
            // 用来对比的初始数据
            // const temp = this.arrFieldConvert(val)
            // temp.forEach(item => {
            //     this.saveCloneMap(item)
            // })
            // 做完对比再置空
            this.wholeListData = {}
            // 初始化计算数量
            // this.initCalNum('num')
        },
        async importList5 () {
            if (this.dtlId === '') {
                this.clientPop('err', '请先添加包件')
                return
            }
            // 测试数据1
            var val = [
                {
                    billId: '1562837339008004600',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '桥梁、涵洞',
                    itemNo: '400章',
                    materialPrice: null,
                    parentId: '0',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '6f716918608b29b90a18af90843549ee',
                    unit: null,
                    structure: []
                },
                {
                    billId: '1562837339008004900',
                    budgetPrice: null,
                    identification: '清单',
                    isDetailed: 0,
                    itemName: '下部结构钢筋',
                    itemNo: '403-2',
                    materialPrice: null,
                    parentId: '6f716918608b29b90a18af90843549ee',
                    quantity: null,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 0,
                    thisLevelId: '1907b26f0fd9924a8fe28c844fb3338e',
                    unit: 'kg',
                    structure: []
                },
                {
                    billId: '1562837339008004900',
                    budgetPrice: 100,
                    identification: '清单',
                    isDetailed: 1,
                    itemName: '带肋钢筋（HRB335、HRB400）',
                    itemNo: '403-2-b',
                    materialPrice: null,
                    parentId: '1907b26f0fd9924a8fe28c844fb3338e',
                    quantity: 10,
                    structureName: null,
                    structureNamePaths: null,
                    structurePaths: null,
                    termIsDetailed: 1,
                    thisLevelId: '20ea07deae3123bde82170ddd1e22c78',
                    unit: 'kg',
                    structure: [
                        {
                            billId: null,
                            budgetPrice: null,
                            identification: null,
                            isDetailed: null,
                            itemName: null,
                            itemNo: null,
                            materialPrice: null,
                            parentId: '20ea07deae3123bde82170ddd1e22c78',
                            quantity: 10,
                            structureName: '圆墩',
                            structureNamePaths: '桥梁、涵洞-下部构造-桥墩-圆墩',
                            structurePaths:
                                '[{"isLeaf":0,"listId":"086f34f9bc7446a29a5aa4660e099a44","parentId":"0","structureId":"1567804727290949633","structureName":"桥梁、涵洞","structureNo":"4","structureType":0},{"isLeaf":0,"listId":"58604bdca9274929a370ae9c65c79b41","parentId":"086f34f9bc7446a29a5aa4660e099a44","structureId":"1567804727290949634","structureName":"下部构造","structureNo":"4-3","structureType":0},{"isLeaf":0,"listId":"dc6596819f594d31a8851819b1733de9","parentId":"58604bdca9274929a370ae9c65c79b41","structureId":"1567804727290949635","structureName":"桥墩","structureNo":"4-3-2","structureType":0},{"isLeaf":1,"listId":"4e4c166baf6d45dfbd772597db08ec36","parentId":"dc6596819f594d31a8851819b1733de9","structureId":"1567804727290949636","structureName":"圆墩","structureNo":"4-3-2-1","structureType":0}]',
                            termIsDetailed: null,
                            thisLevelId: '4e4c166baf6d45dfbd772597db08ec36',
                            unit: null,
                            structure: null
                        }
                    ]
                }
            ]
            // 备份一个对比选择数据是否包含已有数据
            const cloneMapTableData = JSON.parse(JSON.stringify(this.mapTableData))
            //  如果没选数据
            if (val.length === 0) {
                // 重置
                this.cloneTableData = []
                this.mapTableData = {}
                this.deleteTableData = []
                this.addList = []
                this.cloneMapInitTableData = {}
                this.tableData = []
                return
            }
            // 处理客户端重复数据
            val = this.backEndBug(val)
            // this.setSelectedInfo(val)
            // openAppClient('/showSelectedData', '选择结果', function () {})
            // 转换前端显示数据
            // arrFieldConvert changeState会在此时定义
            await this.$emit('change', this.arrToTree(this.arrFieldConvert(val, cloneMapTableData)))
            // 重置table，不然table展开时数据不刷新
            this.tableRefState = false
            setTimeout(() => {
                this.tableRefState = true
            }, 0)
            this.saveMapTableData()
            // saveMapTableData会使changeState -1还原0，找不到原因
            const valListId = val.map(item => item.thisLevelId)
            Object.keys(this.mapTableData).forEach(item2 => {
                if (item2 === '0') return
                const temp = valListId.includes(item2)
                if (temp === false) {
                    this.mapTableData[item2].changeState = -1
                    console.log('item2', item2)
                }
            })
            // 用来对比的初始数据
            // const temp = this.arrFieldConvert(val)
            // temp.forEach(item => {
            //     this.saveCloneMap(item)
            // })
            // 做完对比再置空
            this.wholeListData = {}
            // 初始化计算数量
            // this.initCalNum('num')
        },
        // 选择数据还原之前已有数据
        restMapTableData (cloneMapTableData) {
            console.log('执行222')
            Object.keys(this.mapTableData).forEach(item => {
                if (cloneMapTableData[item]) {
                    this.mapTableData[item] = cloneMapTableData[item]
                }
            })
        },
        // 处理后端id重复bug
        backEndBug (val) {
            const temp = []
            // 结构层的id
            val.forEach(item => {
                item.uuid = getUuid()
                item.structure.forEach(item2 => {
                    temp.push(item2.thisLevelId)
                })
            })
            // 子级的id和结构层id相同删除
            val.forEach((item, index) => {
                if (temp.includes(item.thisLevelId)) {
                    delete val[index]
                }
            })
            console.log('backEndBug val', val)
            return val
        },
        // eslint-disable-next-line no-unused-vars
        async onload (row, treeNode, resolve) {
            let result
            if (row.children?.length > 0) {
                result = row.children
            } else {
                // 如果不是最子级，就从接口取
                if (!row.isAllLeaf) {
                    result = await this.getData(row.listId)
                } else {
                    // 是最子级，则初始为空，合并新增数据，并设为非最子级
                    result = []
                    // row.isLeaf = 0
                }
                // 如果有缓存数据，说明是点击的 “添加子级” 按钮
                if (this.addList.length > 0) {
                    result = result.concat(this.addList)
                    this.addList = []
                }
            }
            row.treeNode = treeNode
            row.resolve = resolve
            row.children = result
            // this.mapTableData[row.listId] = row
            // this.saveCloneMap(row)
            // result.forEach(item => {
            //     this.mapTableData[item.listId] = item
            //     // this.saveCloneMap(item)
            // })
            // console.log('cloneMapInitTableData', this.cloneMapInitTableData)
            // console.log('this.mapTableData', this.mapTableData)
            // console.log('this.deleteTableData', this.deleteTableData)
            // result.forEach(item=>{
            //     if(row.unit !== '总额' && row.itemIsDetailed) {
            //         if(item.unitPrice !== row.unitPrice) {
            //             item.unitPrice = row.unitPrice
            //             this.onCalcAmount(item)
            //         }
            //     }
            // })
            // 结构初始数据
            if (row.isLeaf === 1) {
                // 和结构是同一个内存地址，新增项需要先删掉结构，否则新增的childrren和applyStructureList会互相指向
                this.$set(row, 'applyStructureList', JSON.parse(JSON.stringify(result)))
                // row.applyStructureList = result
            }
            resolve(result)
        },
        // 添加子级
        async addChilden (row, levelIsTotal) {
            if (!row.children) return
            // eslint-disable-next-line no-debugger
            // debugger
            row.isLeaf = 0
            row.price = ''
            // 删除结构
            for (let i = 0; i < row.children.length; i++) {
                if (row.children[i].label !== '项') {
                    row.children.splice(i--, 1)
                }
            }
            const uid = await this.uidBuilder({ num: 1 })
            // 项（第一层children）
            const addData = {
                amount: 0,
                applyStructureList: row.applyStructureList,
                children: [],
                hasChildren: true,
                billId: this.tenderId,
                changeState: 1,
                code: '', // 细目编码
                codeName: '', // 细目名称
                isAllLeaf: 0, // 是否所有最子级
                isLeaf: 1,
                isListLeaf: 0, // 是否是清单最子级
                isUpdateAmountState: false,
                isUpdateNumState: false,
                isUpdatePriceState: false,
                label: '项', // 标识
                listId: uid, // 本级id
                num: 0, // 数量
                packageId: this.packageId,
                parentId: row.listId, // 父级ID
                price: row.price,
                priceType: 0,
                // recordId: '',
                unit: '' // 计量单位
            }
            // 增加项，没有结构或子级就无法新增
            if (row.children) row.children.push(addData)
            // 增加项里的结构（第二层childrren）
            const children = await this.addStructure(row, uid)
            this.$set(addData, 'children', children)
            this.saveMapTableData()
            let childrenHand = {}
            // 计算新加入行金额
            children.forEach(item => {
                childrenHand = this.mapTableData[item.listId]
                childrenHand.amount = Math.round(childrenHand.price * childrenHand.num)
            })
            // 向上汇总数量
            // eslint-disable-next-line no-unreachable
            this.recurCount({
                parentId: childrenHand.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                childrenHand,
                str: 'num',
                type: 'float'
            })
            if (levelIsTotal === false) {
                // 向上汇总金额
                this.recurCount({
                    parentId: childrenHand.parentId,
                    rootId: '0',
                    listField: 'listId',
                    parentField: 'parentId',
                    childrenHand,
                    str: 'amount'
                })
            }
        },
        onDelNode (row) {
            const callBack = () => {
                row.changeState = -1
                // 如果修改的是结构，修改父级的applyStructureList为-1
                if (row.structureName) {
                    console.log('this.mapTableData[row.parentId]', this.mapTableData[row.parentId])
                    this.mapTableData[row.parentId].applyStructureList.forEach(item => {
                        if (item.listId === row.listId) {
                            item.deleteState = 1
                        }
                    })
                }
                // 删除tableData与mapTableData
                const temp = row => {
                    if (row === undefined) {
                        // 清单没数据，包件起止桩号肯定是空
                        this.$emit('startEndStake', '', this.dtlIndex)
                        return
                    }
                    // console.log('row', row)
                    const _row = JSON.parse(JSON.stringify(row)) // 用来寻找上级
                    // 父级的chilren
                    const siblings = this.mapTableData[row.parentId].children
                    // 在父级的chilren里删掉当前节点
                    const index = siblings.findIndex(item => {
                        if (item.listId === row.listId) {
                            // 不是新增数据变为-1
                            // if (row.changeState !== 1) {
                            // if (row.listId) {
                            //     // 删除映射表
                            //     // delete this.mapTableData[row.listId]
                            //     // 删除清单所有数据（已选功能）
                            //     // delete this.wholeListData[row.listId]
                            // }
                            row.changeState = -1
                            // delete this.wholeListData[row.listId]
                            // wholeListData也要做改变，已选数据需要
                            // this.wholeListData[row.listId].changeState = -1
                            // this.deleteTableData.push(row)
                            // }
                            // 向下寻找子级变为-1
                            const temp2 = row => {
                                while (row) {
                                    row = row.children
                                    if (!row) break
                                    // if(row===null) return
                                    if (Array.isArray(row)) {
                                        row.forEach(item => {
                                            // if (item.changeState !== 1) {
                                            item.changeState = -1
                                            // delete this.wholeListData[item.listId]
                                            // wholeListData也要做改变，已选数据需要
                                            // this.wholeListData[item.listId].changeState = -1
                                            // this.deleteTableData.push(item)
                                            // 删除映射表
                                            // if (item.listId) {
                                            //     delete this.mapTableData[item.listId]
                                            // }
                                            // 删除清单所有数据（已选功能）
                                            // delete this.wholeListData[row.listId]
                                            // }
                                            temp2(item)
                                        })
                                    }
                                }
                            }
                            temp2(row)
                            // 像上寻找父级变为2
                            const levelIds = getItemOfTreeArr(this.tableData, 'listId', item.listId)
                            for (let i = 0; i < levelIds.length - 1; i++) {
                                if (levelIds[i].changeState !== 1) {
                                    levelIds[i].changeState = 2
                                }
                            }
                            return true
                        }
                    })
                    siblings.splice(index, 1)
                    // 如果父级的长度为0则继续往上寻找删除
                    if (siblings.length === 0) {
                        // console.log('000row', row)
                        // 如果顶级已经被删除，跳出
                        if (_row === undefined) return
                        const level = this.mapTableData[this.mapTableData[_row.parentId].listId]
                        temp(level)
                    }
                }
                temp(row)
                // 删除wholeListData
                if (Object.values(this.wholeListData).length !== 0) {
                    const row2 = this.wholeListData[row.listId]
                    console.log('row2', row2)
                    row2.changeState = -1
                    const temp2 = row => {
                        if (row === undefined) return
                        // console.log('row', row)
                        const _row = JSON.parse(JSON.stringify(row)) // 用来寻找上级
                        // 父级的chilren
                        const siblings = this.wholeListData[row.parentId].children
                        // 在父级的chilren里删掉当前节点
                        console.log('siblings', siblings)
                        const index = siblings.findIndex(item => {
                            if (item.listId === row.listId) {
                                console.log('执行了111')
                                // 不是新增数据变为-1
                                // if (row.changeState !== 1) {
                                // if (row.listId) {
                                //     // 删除映射表
                                //     // delete this.mapTableData[row.listId]
                                //     // 删除清单所有数据（已选功能）
                                //     // delete this.wholeListData[row.listId]
                                // }
                                row.changeState = -1
                                // wholeListData也要做改变，已选数据需要
                                // this.wholeListData[row.listId].changeState = -1
                                // this.deleteTableData.push(row)
                                // }
                                // 向下寻找子级变为-1
                                const temp2 = row => {
                                    while (row) {
                                        row = row.children
                                        if (!row) break
                                        // if(row===null) return
                                        if (Array.isArray(row)) {
                                            row.forEach(item => {
                                                // if (item.changeState !== 1) {
                                                item.changeState = -1
                                                // wholeListData也要做改变，已选数据需要
                                                // this.wholeListData[item.listId].changeState = -1
                                                // this.deleteTableData.push(item)
                                                // 删除映射表
                                                // if (item.listId) {
                                                //     delete this.mapTableData[item.listId]
                                                // }
                                                // 删除清单所有数据（已选功能）
                                                // delete this.wholeListData[row.listId]
                                                // }
                                                temp2(item)
                                            })
                                        }
                                    }
                                }
                                temp2(row2)
                            }
                        })
                        siblings.splice(index, 1)
                        // 如果父级的长度为0则继续往上寻找删除
                        if (siblings.length === 0) {
                            // console.log('000row', row)
                            // 如果顶级已经被删除，跳出
                            if (_row === undefined) return
                            const level =
                                this.wholeListData[this.wholeListData[_row.parentId].listId]
                            temp2(level)
                        }
                    }
                    temp2(row)
                }
                this.initCalNum('num')
                this.initCalNum('amount')
                // console.log('this.tableData', this.tableData)
                // console.log('this.deleteTable', this.deleteTableData)
                // console.log('this.mapTableData', this.mapTableData)
            }
            this.clientPop(
                'info',
                '是否删除选择的细目？删除是将本级及下级全部删除，请谨慎操作！',
                callBack
            )
        },
        // 输入后计划金额
        onCalcAmount (row) {
            row.amount = Math.round(row.num * row.price)
            // 向上汇总金额
            this.recurCount({
                parentId: row.parentId,
                rootId: '0',
                listField: 'listId',
                parentField: 'parentId',
                row,
                str: 'amount'
            })
        },
        // 递归统计父级
        recurCount ({ parentId, rootId, listField, parentField, row, str, type = 'int' }) {
            const parent = this.mapTableData[parentId]
            console.log('parentId', parentId)
            console.log('parent', parent)
            // console.log('str', str)
            // console.log('parent', parent)
            // console.log('name', parent.label, parent.code)
            // console.log('this.mapTableData', this.mapTableData)
            // 统计所有同级
            if (parent === undefined) return
            // num只统计到清单最明细级
            if (str === 'num' && parent.label === '清单' && parent.isListLeaf === 0) return
            // console.log('parent', parent)
            const countSibling = parent.children?.reduce((prev, item) => {
                if (type === 'int') {
                    return prev + Math.round(item[str])
                } else {
                    // console.log('item[str]', item[str])
                    return prev + parseFloat(parseFloat(item[str]).toFixed(4))
                }
            }, 0)
            // console.log('countSibling', countSibling)
            // 赋值汇总数据给父级
            parent[str] = countSibling // 赋值汇总数据给父级
            // 到根节点
            if (parentId === rootId) {
                return
            }
            // 未到根节点则继续遍历父节点
            return this.recurCount({
                parentId: parent[parentField],
                rootId,
                listField,
                parentField,
                row,
                str,
                type: str === 'num' ? 'float' : 'int'
            })
        },
        tableRowClassName ({ row }) {
            return `class-${row.listId}`
        },
        async uidBuilder (params, type = 'str') {
            let temp = []
            await uidBuilder(params).then(res => {
                temp = type === 'str' ? res[0] : res
            })
            return temp
        }
        // refreshLoadTree (parentId) {
        //     // 根据父级id取出对应节点数据
        //     // const { row, treeNode, resolve } = this.mapTableData[parentId]
        //     let children = this.mapTableData[parentId].children
        //     const tableRef = this.$refs.tableRef
        //     this.$set(tableRef.store.states.lazyTreeNodeMap, parentId, children)
        // },
    }
}
</script>
<style lang="scss" scoped>
::v-deep .hide-icon {
    .el-table__expand-icon {
        display: none;
    }
}
::v-deep.el-table__row {
    .cell {
        display: flex;
        align-items: center;
    }
    td:nth-child(6),
    td:nth-child(7),
    td:nth-child(8) {
        .cell {
            justify-content: flex-end;
        }
    }
}
::v-deep .el-popover__reference-wrapper {
    display: flex;
    height: 100%;
}
.ruleMessage {
    margin-bottom: 10px;
    margin-left: 10px;
    color: red;
}

::v-deep .el-tree-node {
    display: flex;
    justify-content: center;
}

::v-deep .el-tree-node__content {
    line-height: 25px;
    display: inline-block;
    width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding-right: 30px;
    // word-break: break-all;
    // text-overflow: ellipsis;
    // display: -webkit-box;
    // -webkit-box-orient: vertical;
    // -webkit-line-clamp: 2;
    // overflow: hidden;
}
.e-table {
    background: #fff;
}
</style>
